/*
 * This file is part of quickReminder, a software for gamers
 *
 * Copyright (C) 2006-2008 Lucas Romero
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Drawing;
using System.Drawing.Imaging;
using System.ComponentModel;
using System.IO;
using HtmlAgilityPack;
using System.Text.RegularExpressions;

namespace LucasCode
{
    [Serializable]
    public class MatchContestant
    {
        private List<MatchPlayer> m_Players = new List<MatchPlayer>();
        private string m_Name;
        private string m_ID;
        private Bitmap m_Logo;
        private MatchContestantTypes m_Type = MatchContestantTypes.Team;
        private bool m_IsOwnerTeam = false;

        public MatchContestant()
        {
            //m_Logo = (Bitmap)Image.FromFile("anonymous.png");
        }

        public MatchPlayer[] getMemberList()
        {
            if (m_Type == MatchContestantTypes.Individual)
                return new MatchPlayer[0];
            return getMemberList(this);
        }

        public static MatchPlayer[] getMemberList(MatchContestant team)
        {
            return getMemberList(team.ID);
        }

        public static MatchPlayer[] getMemberList(string teamid)
        {
            List<MatchPlayer> players = new List<MatchPlayer>();
            if (string.IsNullOrEmpty(teamid))
                return players.ToArray();

            HtmlAgilityPack.HtmlDocument d = new HtmlAgilityPack.HtmlDocument();
            string html = MatchHelpers.GetHTML(@"http://www.esl.eu/team/members/" + teamid);
            d.LoadHtml(html);
#if DEBUG
            d.OptionOutputAsXml = true;
            d.Save("teamdump.xml");
#endif
            HtmlNode MainNode = d.DocumentNode.SelectSingleNode(@"//div[@id=""main_content""]");

            HtmlNodeCollection members = MainNode.SelectNodes(@"div/table/tr/td/table/tr/td/b/a");
            if (members == null)
                return players.ToArray();

            System.Collections.Specialized.StringCollection barredmemberids = new System.Collections.Specialized.StringCollection();
            HtmlNodeCollection BarredMembersNodes = MainNode.SelectNodes(@"div/div/table/tr");
            if (BarredMembersNodes != null)
            {
                foreach (HtmlNode n in BarredMembersNodes)
                {
                    barredmemberids.Add(MatchHelpers.getIDFromLink(n.SelectSingleNode("td[2]/a").Attributes["href"].Value));
                }
            }
            
            foreach (HtmlNode n in members)
            {
                MatchPlayer p = new MatchPlayer(n.InnerText);
                p.ESLNick = n.InnerText;
                p.CurrentNick = n.InnerText;
                p.UserID = MatchHelpers.getIDFromLink(n.Attributes["href"].Value);
                if (barredmemberids.Contains(p.UserID))
                    p.IsBarred = true;

                HtmlNode GameIDNode = n.SelectSingleNode(@"../../../../../../td[5]");
                if (GameIDNode != null)
                {
                    foreach (HtmlNode GameID in GameIDNode.SelectNodes("div"))
                    {
                        string[] gameaccount = GameID.InnerText.Split(new string[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
                        //valid gameaccount with at least type and value?
                        if (gameaccount.Length < 2)
                            continue;
                        string IDType = gameaccount[0].Trim();
                        //strip ":" from ID-type
                        if (IDType.EndsWith(":"))
                            IDType = IDType.Substring(0, IDType.Length - 1);
                        string id = gameaccount[1].Trim();
                        p.GameAccountList[IDType].Value = id;
                    }
                }
                players.Add(p);
            }
            return players.ToArray();
        }

        public string Name
        {
            get
            {
                return m_Name;
            }
            set
            {
                m_Name = value;
            }
        }

        public string ID
        {
            get
            {
                return m_ID;
            }
            set
            {
                m_ID = value;
            }
        }

        public MatchPlayer[] Players
        {
            get
            {
                return m_Players.ToArray();
            }
            set
            {
                m_Players.Clear();
                foreach (MatchPlayer p in value)
                    AddPlayer(p);
            }
        }
        [XmlIgnore]
        public int PlayerCount
        {
            get
            {
                return m_Players.Count;
            }
            set
            {
            }
        }
        [XmlIgnore]
        public Bitmap Logo
        {
            get
            {
                return m_Logo;
            }
            set
            {
                m_Logo = value;
            }
        }
        [XmlElementAttribute("Logo")]
        public byte[] PictureByteArray
        {
            get 
            {
                if (m_Logo != null)
                {
                    TypeConverter BitmapConverter =
                         TypeDescriptor.GetConverter(m_Logo.GetType());
                    return (byte[])
                         BitmapConverter.ConvertTo(m_Logo, typeof(byte[]));
                }
                else
                    return null;
            }
            set 
            { 
                if (value != null)
                    m_Logo = new Bitmap(new MemoryStream(value)); 
                else
                    m_Logo = null; 
            }
        }

        public MatchContestantTypes Type
        {
            get
            {
                return m_Type;
            }
            set
            {
                m_Type = value;
            }
        }

        public bool IsOwnerTeam
        {
            get
            {
                return m_IsOwnerTeam;
            }
            set
            {
                m_IsOwnerTeam = value;
            }
        }

        [XmlIgnore]
        public string URL
        {
            get
            {
                if (string.IsNullOrEmpty(m_ID))
                    return string.Empty;
                switch (m_Type)
                {
                    case MatchContestantTypes.Individual:
                        return String.Concat("http://www.esl.eu/player/", m_ID, "/");
                    case MatchContestantTypes.Team:
                        return String.Concat("http://www.esl.eu/team/", m_ID, "/");
                    default:
                        return string.Empty;
                }
            }
        }

        public void AddPlayer(MatchPlayer player)
        {
            MatchPlayer existing = searchDuplicate(player);
            if (existing != null)
            {
                m_Players.Remove(existing);
                player.AddActions(existing.Actions);
                player.AddNicks(existing.Names);
                player.HasAequitasLog |= existing.HasAequitasLog;
                player.IsArchiveOwner |= existing.IsArchiveOwner;
                player.IsBarred |= existing.IsBarred;
                if (string.IsNullOrEmpty(player.UserID))
                    player.UserID = existing.UserID;
                if (string.IsNullOrEmpty(player.ESLNick))
                    player.ESLNick = existing.ESLNick;
                if (string.IsNullOrEmpty(player.GameID))
                    player.GameID = existing.GameID;
                player.GameAccountList.Add(existing.GameAccountList.ToArray());
            }
            m_Players.Add(player);
            player.Team = this;
        }

        public MatchPlayer searchDuplicate(MatchPlayer player)
        {
            foreach (MatchPlayer p in m_Players)
            {
                if (p.Equals(player))
                {
                    return p;
                }
            }
            return null;
        }
    }
}
